home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
501-525
/
disk_509
/
pckeymap
/
pckeymap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
18KB
|
582 lines
/* $Revision Header *** Header built automatically - do not edit! ***********
*
* (C) Copyright 1991 by Peter Vorwerk
*
* Name .....: PCKeyMap.c
* Created ..: Saturday 16-Mar-91 10:39
* Revision .: 0
*
* Date Author Comment
* ========= ======== ====================
* 16-Mar-91 Peter Vorwerk Created this file!
*
* $Revision Header ********************************************************/
#define REVISION 0
#define VERSION 1
#include <stdio.h>
#include <functions.h>
#include <exec/execbase.h>
#include <exec/tasks.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <exec/devices.h>
#include <exec/io.h>
#include <exec/libraries.h>
#include <exec/interrupts.h>
#include <exec/nodes.h>
#include <devices/input.h>
#include <devices/inputevent.h>
#include <intuition/intuitionbase.h>
#include <intuition/intuition.h>
#include <libraries/arpbase.h>
#include <janus/janus.h>
void Input_Code(void); /* Predefine the ASM-Handler */
struct MsgPort *IPort = NULL;
struct IOStdReq *InputRequest = NULL;
struct Interrupt Input_Handler;
struct Task *MyTask;
ULONG User_Routine;
ULONG Qualifier , Code , MySignal, data , SigNum = 0L;
/* These codes are PC RawCodes.
PC_ALT means press the ALT key
PC_nALT means release the ALT key
PC_x means press the x key of the numeric block */
/* Remember, you MUST press and relase control keys as CTRL, ALT
or SHIFT, while normal keys need only be pressed. */
#define PC_ALT (UBYTE) '\070'
#define PC_nALT (UBYTE) '\270'
#define PC_0 (UBYTE) '\122'
#define PC_1 (UBYTE) '\117'
#define PC_2 (UBYTE) '\120'
#define PC_3 (UBYTE) '\121'
#define PC_4 (UBYTE) '\113'
#define PC_5 (UBYTE) '\114'
#define PC_6 (UBYTE) '\115'
#define PC_7 (UBYTE) '\107'
#define PC_8 (UBYTE) '\110'
#define PC_9 (UBYTE) '\111'
struct IntuitionBase *IntuitionBase;
struct Library *JanusBase = NULL;
UBYTE *KeyB = NULL;
UBYTE *IntR = NULL;
/******************************
* *
* PCKeyB() *
* *
******************************/
/* Calculate the address of the keyboard-register (KeyB) and
the keyboard-interrupt (IntR) of the XT/AT board. By writing
a value in the KeyB and sending the interrupt, the XT/AT will
assume we have pressed or released this key on the keyboard. */
void PCKeyB(void)
{
UBYTE *ptr;
UWORD *offset;
/* Die Keyboard Addresse ist als positiver Offset 0x72 in der Janus.library abgelegt. */
/* Achtung! Im 'Amiga SYSTEM-Handbuch wird die feste Addresse 0x7ffff als Keyboard Addresse
genannt. Bei meinem Amiga 2000 mit AT Karte stimmte dies, jedoch nicht beim SideCar.
Die Offset Struktur wurde experimentell ( teilweiser Speicherdump vom Programm
PCWINDOW ) ermittelt. Zum Glück stimmte wenigstens die Adresse des Interrupts,
so konnte ich im Speicher nach dem Auftreten dieser Kombination suchen und die
nähere Umgebung disassemblieren. */
/* Keyboard address. Please note 0x7ffff is NOT the correct address in ALL Systems.
You must calculate it by contents of (JanusBase + 0x72) + 0x7e000 !! */
/* I found this by disassembling the file PCWINDOW. */
KeyB = (UBYTE *) JanusBase;
KeyB += 0x72;
offset = (UWORD *) KeyB;
ptr = (UBYTE *) GetJanusStart();
KeyB = ptr + 0x7e000;
KeyB += *offset;
IntR = ptr + 0x7fffb; /* Addresse aus 'Amiga SYSTEM-Handbuch' */
}
/*******************************
* *
* Handler() *
* *
*******************************/
/* This is the C-code of my handler. This function will
test, if a key has been pressed or released. If so this
function test, if the actual window title start with the
sequence " PC ". If this is true also, send a signal to
the main process. The main process will determine which
action should be done. */
struct InputEvent *Handler(struct InputEvent *Input, ULONG *Data)
{
char *s;
struct InputEvent *Next;
Next = Input;
while(Next)
{
/* Is the Event produced of the keyboard ? */
if (Next->ie_Class == IECLASS_RAWKEY)
{
/* Starts the actual window with the sequence " PC " ? */
s = (char *) IntuitionBase->ActiveWindow->Title;
if (strncmp(" PC ",s,4) == 0)
{
/* Save the Code and the Qualifier of the last Event ... */
Qualifier = Next->ie_Qualifier;
Code = Next->ie_Code;
/* ... and send a signal to the main process. */
Signal(MyTask,MySignal);
}
}
/* Search for the next Event. */
Next = Next->ie_NextEvent;
}
/* Return the Event to the System, so that the other handlers
can use it too. */
return(Input);
}
/***********************
* *
* InitHandler() *
* *
***********************/
/* Start the Handler. */
void InitHandler(void)
{
data = 0L;
User_Routine = (ULONG) Handler;
Input_Handler.is_Data = (APTR) &data;
Input_Handler.is_Code = (void (*)())Input_Code;
Input_Handler.is_Node.ln_Pri = 51;
Input_Handler.is_Node.ln_Name = "PCKeyMap-Handler";
InputRequest->io_Data = (APTR) &Input_Handler;
InputRequest->io_Command = IND_ADDHANDLER;
DoIO((struct IORequest *) InputRequest);
}
/**********************
* *
* Input_Code() *
* *
**********************/
/* This is the assembler routine of the handler. We need it,
because the system will send the parameter in a register.
But a C-funtion search for the parameter on the stack. */
#asm
public _geta4
public _Input_Code
_Input_Code:
move.l a4,-(sp)
jsr _geta4
movem.l a0/a1,-(sp)
move.l _User_Routine,a0
jsr (a0)
movem.l (sp)+,a0/a1
move.l (sp)+,a4
rts
#endasm
/********************
* *
* CloseAll() *
* *
********************/
/* Normaly this function is not called. Only if an error
occurs during the setup this function will be called.
Try to close all open stuff. */
void CloseAll(void)
{
if (SigNum)
{
FreeSignal(SigNum);
}
if (InputRequest->io_Device)
{
CloseDevice((struct IORequest *) InputRequest);
}
if (InputRequest)
{
DeleteStdIO(InputRequest);
}
if (IPort)
{
DeletePort(IPort);
}
exit(10);
}
/************************
* *
* OpenAll() *
* *
************************/
/* Open the libraries and the ports. */
void OpenAll(void)
{
if (!(JanusBase = ArpOpenLibrary("janus.library",0L)))
{
Printf("\nCan't find JANUS.library\nAborted...\n");
exit(10);
}
if (!(IPort = CreatePort(NULL,0L)))
{
CloseAll();
}
if (!(InputRequest = CreateStdIO(IPort)))
{
CloseAll();
}
if (OpenDevice("input.device",0L,(struct IORequest *) InputRequest,0L))
{
CloseAll();
}
/* Get a signal for our own Task */
if ((SigNum = AllocSignal(-1L)) < 0)
{
CloseAll();
}
MySignal = 1 << SigNum;
/* Now start the Handler. */
InitHandler();
}
/********************
* *
* SendKey() *
* *
********************/
/* This function will send the values to the keyboard-register and
send the interrupt. */
void SendKey(UBYTE k1, UBYTE k2, UBYTE k3)
{
*KeyB = PC_ALT;
*IntR = '\377'; /* 0xff */
Delay(1);
*KeyB = k1;
*IntR = '\377'; /* 0xff */
Delay(1);
*KeyB = k2;
*IntR = '\377'; /* 0xff */
Delay(1);
*KeyB = k3;
*IntR = '\377'; /* 0xff */
Delay(1);
*KeyB = PC_nALT;
*IntR = '\377'; /* 0xff */
Delay(1);
}
/********************
* *
* CheckKey() *
* *
********************/
/* Check which key has been pressed. */
void CheckKey(void)
{
switch(Code)
{
case 0x00: if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
{
SendKey(PC_1,PC_2,PC_6);
}
else
{
SendKey(PC_0,PC_9,PC_6);
}
break;
case 0x01: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
{
if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
{
SendKey(PC_1,PC_7,PC_3);
}
else
{
SendKey(PC_0,PC_4,PC_9);
}
}
break;
case 0x02: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
{
if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
{
SendKey(PC_0,PC_6,PC_4);
}
else
{
SendKey(PC_0,PC_5,PC_0);
}
}
break;
case 0x03: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
{
if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
{
SendKey(PC_0,PC_3,PC_5);
}
else
{
SendKey(PC_0,PC_5,PC_1);
}
}
break;
case 0x04: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
{
if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
{
SendKey(PC_0,PC_3,PC_6);
}
else
{
SendKey(PC_0,PC_5,PC_2);
}
}
break;
case 0x05: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
{
if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
{
SendKey(PC_0,PC_3,PC_7);
}
else
{
SendKey(PC_0,PC_5,PC_3);
}
}
break;
case 0x06: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
{
if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
{
SendKey(PC_0,PC_9,PC_4);
}
else
{
SendKey(PC_0,PC_5,PC_4);
}
}
break;
case 0x07: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
{
if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
{
SendKey(PC_0,PC_3,PC_8);
}
else
{
SendKey(PC_0,PC_5,PC_5);
}
}
break;
case 0x08: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
{
if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
{
SendKey(PC_0,PC_4,PC_2);
}
else
{
SendKey(PC_0,PC_5,PC_6);
}
}
break;
case 0x09: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
{
if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
{
SendKey(PC_0,PC_4,PC_0);
}
else
{
SendKey(PC_0,PC_5,PC_7);
}
}
break;
case 0x0a: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
{
if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
{
SendKey(PC_0,PC_4,PC_1);
}
else
{
SendKey(PC_0,PC_4,PC_8);
}
}
break;
case 0x0b: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
{
if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
{
SendKey(PC_0,PC_9,PC_5);
}
else
{
SendKey(PC_0,PC_4,PC_5);
}
}
break;
case 0x0c: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
{
if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
{
SendKey(PC_0,PC_4,PC_3);
}
else
{
SendKey(PC_0,PC_6,PC_1);
}
}
break;
case 0x0d: if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
{
SendKey(PC_1,PC_2,PC_4);
}
else
{
SendKey(PC_0,PC_9,PC_2);
}
break;
case 0x1a: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
{
if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
{
SendKey(PC_1,PC_2,PC_3);
}
else
{
SendKey(PC_0,PC_9,PC_1);
}
}
break;
case 0x1b: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
{
if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
{
SendKey(PC_1,PC_2,PC_5);
}
else
{
SendKey(PC_0,PC_9,PC_3);
}
}
break;
case 0x29: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
{
if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
{
SendKey(PC_0,PC_5,PC_8);
}
else
{
SendKey(PC_0,PC_5,PC_9);
}
}
break;
case 0x2a: if (Qualifier & IEQUALIFIER_LALT || Qualifier & IEQUALIFIER_RALT )
{
if (Qualifier & IEQUALIFIER_LSHIFT || Qualifier & IEQUALIFIER_RSHIFT )
{
SendKey(PC_0,PC_3,PC_4);
}
else
{
SendKey(PC_0,PC_3,PC_9);
}
}
break;
}
}
int main(int argc, char *argv[])
{
if (MyTask = FindTask("PCKeyMap-Handler"))
{
Printf("
PCKeyMap
is already installed !\n");
exit(5);
}
if (!(MyTask = FindTask(NULL)))
{
CloseAll();
}
MyTask->tc_Node.ln_Name = "PCKeyMap-Handler";
/* Set own process name, so we can determine if the program is already in memory. */
OpenAll();
Printf("Installing
PCKeyMap
V%ld.%ld by Peter Vorwerk\t
PUBLIC DOMAIN
\n",VERSION,REVISION);
PCKeyB(); /* Calculate the KeyBoardAddress. */
/* Do forever ... */
for(;;)
{
Wait(MySignal);
CheckKey();
}
/* We will never reach this statement, but my Compiler needs it. */
return(0);
}